package com.is2.patchinglife.manager;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.AsyncTask;
import android.provider.MediaStore;
import android.util.Log;
import android.widget.ImageView;

import com.facebook.Request;
import com.facebook.Request.Callback;
import com.facebook.Response;
import com.facebook.Session;
import com.facebook.model.GraphObject;
import com.facebook.model.GraphUser;
import com.is2.patchinglife.R;

public class ImageManager {
	
	public static Bitmap profileImage = null;						// user custom image
	public static final String image_src_name = "stored_image";		// image base path
	public static final int SELECT_PHOTO = 100;						// service code [to recognize gallery intent result]
	
	private static ImageView user_imageView;
	private static ProgressDialog simpleWaitDialog;
	
	// callback to analyze FQL query results, getting image_url and starting image download [used by XXX]
	private static Request.Callback request_callback = new Callback() {
		@Override
		public void onCompleted(Response response) {
			try {
				GraphObject graphObject = response.getGraphObject();		// request result
				String jsonString = ""+graphObject.getProperty("data");		// get obtained datas
				
				// get image url
				JSONArray jsonURL = new JSONArray(jsonString);
				String url = jsonURL.getJSONObject(0).getString("url");	
				
				downloadImageFromURL(url, user_imageView);		// start image download
			
			} catch (JSONException e) {
				Log.e("ImageManager", "request_callback: JSON ERROR");
				e.printStackTrace();
			}
		}
	};
	
	
	/** Selects default image **/
	public static void selectDefaultImage(ImageView _imgView, Context _context){
		
		// setting user image
		Drawable user_image = _context.getResources().getDrawable(R.drawable.default_user_image);	// get default image
	    _imgView.setImageDrawable(user_image);														// set user image view
	    deleteLocalImage(_context);																	// delete custom image
	
	}
	
	
	/** Selects gallery image **/
	public static void selectGalleryImage(Activity _activity, ImageView _imgView){
		user_imageView = _imgView;
		Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);	// get default photo picker intent
		photoPickerIntent.setType("image/*");						// set file types to show
		
		// start intent and launch _activity.onActivityResultat at the end of execution.
		// SELECT_PHOTO: code needed by onActivityResults [ProfileActivity] to recognize the intent
		_activity.startActivityForResult(photoPickerIntent, ImageManager.SELECT_PHOTO);
	}
	
	
	/** Selects image from Facebook **/
	public static void selectFBimage(final ImageView _imgView){

		// request creation
		Request.newMeRequest(Session.getActiveSession(), new Request.GraphUserCallback() {
			@Override
			public void onCompleted(GraphUser user, Response response) {
				
				if (user != null) {
					user.getId();
					String fqlQuery = "Select url FROM profile_pic WHERE id=\""+user.getId()+"\" AND height=250 AND width=250;";
					
					user_imageView = _imgView;
					
					// show loading dialog
					simpleWaitDialog = ProgressDialog.show(ActivityManager.getInstance().get("ProfileActivity"),"Wait", "Downloading image");
					
					// execute query
					FacebookManager.getResultFQLQuery(fqlQuery,request_callback);	
				}
			}
		}).executeAsync();		// execute request
	}
	
	
	/** Set profile image
	 * _context: application context
	 * requestCode: request code [to recognize associated intent] 
	 * resultCode: result code
	 * imageReturnedIntent: returned image
	 **/
	public static void setProfileImage(Context _context, int requestCode, int resultCode, Intent imageReturnedIntent){
		
		// check intent code
		switch(requestCode) {
	    case SELECT_PHOTO:
	        if(resultCode == Activity.RESULT_OK){  
	        	Uri selectedImage = imageReturnedIntent.getData();			// get image uri
	            String[] filePathColumn = {MediaStore.Images.Media.DATA};	// MIME for required attribute [path]

	            // query to obtain image cursor
	            Cursor cursor = _context.getContentResolver().query(
	                           		selectedImage, filePathColumn, null, null, null);	
	            cursor.moveToFirst();	// return to top

	            // get image file path
	            int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
	            String filePath = cursor.getString(columnIndex);
	            cursor.close();
	            
	            // crop image [square]
	            profileImage = BitmapFactory.decodeFile(filePath);
	            int width = profileImage.getWidth();
	            int height = profileImage.getHeight();
	            int size = Math.min(width,height);		// get lower dimension
	            int x = (width-size)/2;	
	            int y = (height-size)/2;
	            Bitmap croppedBitmap = Bitmap.createBitmap(profileImage,x,y,size,size);
	            
	            // resize image
	            profileImage = Bitmap.createScaledBitmap(croppedBitmap, 250, 250, false);
	            
	            // local image saving
				try {
					// output stream to save image
					FileOutputStream fos = _context.openFileOutput(image_src_name + LocalDataManager.getUser() , Context.MODE_PRIVATE);
					// convert image in PNG and send to output stream
					profileImage.compress(Bitmap.CompressFormat.PNG, 100, fos);
					 // close stream
					fos.close();
					// set imageView
					user_imageView.setImageBitmap(profileImage);			    		
				} catch (FileNotFoundException e) {
					Log.e("FileNotFound", "File not found.");
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				}   
	        }
	    }
	}

	
	/** Loads local image or default image [if not existing] **/
	public static void loadStoredImage(ImageView _imgView, Context _context){
		try {
			// load local image
			FileInputStream fis = _context.openFileInput(image_src_name+LocalDataManager.getUser());
			// set user image
			_imgView.setImageBitmap(BitmapFactory.decodeStream(fis));
			// close connection
			fis.close();
		} catch (FileNotFoundException e) {
			selectDefaultImage(_imgView, _context);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	
	
	/** :::::::::: UTILITY METHODS :::::::::: **/
	
	/** Deletes local image [if exists] **/
	public static void deleteLocalImage(Context _context){
		_context.deleteFile(image_src_name+LocalDataManager.getUser());
	}
	
	/** Download image from URL **/
	public static void downloadImageFromURL(String _url, ImageView _imgView){
		
		// async class to download image
		class ImageDownloader extends AsyncTask<String, Integer, Bitmap> {
			
			
			// executed before doInBackground
	        @Override
	        protected void onPreExecute() {
	            //do nothing	 
	        }
			
			// async request
			@Override
	        protected Bitmap doInBackground(String... param) {
	            return downloadBitmap(param[0]);
	        }

	        // executed after doInBackground
	        @Override
	        protected void onPostExecute(Bitmap result) {
	        	
				try {
					// output stream to save image
		            FileOutputStream fos = LocalDataManager.getFileManager().getContext()
							.openFileOutput(image_src_name + LocalDataManager.getUser(), Context.MODE_PRIVATE);
					// convert image in PNG and send to output stream
					result.compress(Bitmap.CompressFormat.PNG, 100, fos);
		            // close stream
					fos.close();
					
					// set user imageView
					user_imageView.setImageBitmap(result);
		            
				} catch (FileNotFoundException e) {
					Log.e("FileNotFound", "File not found.");
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				}
	            
	           simpleWaitDialog.dismiss();		// dismiss loading dialog
	        }
	        
	        /** Download image **/
	        private Bitmap downloadBitmap(String url) {
	            
	        	// initialize default HTTP client object
	            final DefaultHttpClient client = new DefaultHttpClient();
	 
	            // create HttpGet request [with url]
	            final HttpGet getRequest = new HttpGet(url);
	            
	            try {
	            	// execute request
	                HttpResponse response = client.execute(getRequest);
	 
	                // check 200 OK for success
	                final int statusCode = response.getStatusLine().getStatusCode();
	                if (statusCode != HttpStatus.SC_OK) {
	                    Log.e("ImageDownloader", "Error " + statusCode + 
	                          " while retrieving bitmap from " + url);
	                    return null;
	                }
	 
	                // get image
	                final HttpEntity entity = response.getEntity();
	                if (entity != null) {
	                    InputStream inputStream = null;
	                    try {
	                        // getting stream content 
	                        inputStream = entity.getContent();
	 
	                        // decoding stream data into image Bitmap
	                        final Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
	                        return bitmap;
	                        
	                    } finally {
	                        if (inputStream != null) {
	                            inputStream.close();
	                        }
	                        entity.consumeContent(); 	// entity content no longer required
	                    }
	                }
	            } catch (Exception e) {
	                getRequest.abort();
	                Log.e("ImageDownloader", "Something went wrong while" +
	                      " retrieving bitmap from " + url + e.toString());
	            } 
	            return null;
	        }
	    }
		
		user_imageView = _imgView;				// the method can be called directly
		new ImageDownloader().execute(_url);	// download
	}
	
	
	/** Shows "not connected to Facebook" alert **/
	public static void askLoginDialog(final Activity _caller){
	    AlertDialog.Builder builder=new AlertDialog.Builder(_caller);
		builder.setTitle("ALERT");
		builder.setMessage("You need to be connected to Facebook to download your profile image.");
		builder.setCancelable(true);
   
		builder.setNegativeButton("Ok", new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
				return;			
			}
		});
		
		AlertDialog alert=builder.create();
		alert.show();
    }
}
